<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <title>教程中，轨迹控制器用法</title>
    <style>
      body {
        margin: 0;
        overflow: hidden;
        /* 隐藏body窗口区域滚动条 */
      }
    </style>
    <!--引入three.js三维引擎-->
    <!-- <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script> -->
    <!-- <script src="http://www.yanhuangxueyuan.com/threejs/build/three.js"></script> -->
    <!-- Three.js-master 包示例中的用法 examples/js/controls/OrbitControls.js  版本要匹配-->
    <script src="http://www.yanhuangxueyuan.com/3D/example/three.min.js"></script>
    <script src="../../util/OrbitControls.js"></script>
  </head>
  <body>
    <script type="module">
      import { RAFTime } from "../../util/index.js";
      /**
       * 创建场景对象Scene
       */
      var scene = new THREE.Scene();

      /**
       * 辅助坐标系 参数250表示坐标系大小，可以根据场景大小去设置
       */
      var axisHelper = new THREE.AxisHelper(1000);
      scene.add(axisHelper);
      /**
       * 创建 通用形状的几何体
       */
      // var geometry = new THREE.SphereGeometry(60, 10, 10); //创建一个球体几何对象
      // var geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
      // var geometry = new THREE.CylinderGeometry(50, 50, 100, 50);// 圆柱  参数：圆柱面顶部、底部直径50,50   高度100  圆周分段数
      var geometry = new THREE.IcosahedronGeometry(50); // 正二十面体 参数是大小
      // MeshLambertMaterial 漫反射 材质
      var material = new THREE.MeshLambertMaterial({
        color: 0x0000ff,
        transparent: true,
        opacity: 0.7,
        // wireframe: true,
      }); //材质对象Material
      var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
      scene.add(mesh); //网格模型添加到场景中

      // 多个物体
      var geometry1 = new THREE.SphereGeometry(60, 10, 10); //创建一个球体几何对象
      // MeshPhongMaterial 镜面反射 材质
      var material1 = new THREE.MeshPhongMaterial({
        color: 0xff0000,
        specular: 0x4488ee,
        shininess: 12,
        // transparent: true,
        // opacity: 0.1,
        // wireframe: true,
      }); //材质对象Material
      var mesh1 = new THREE.Mesh(geometry1, material1);
      mesh1.translateY(-120); //沿Y轴正方向平移120
      mesh1.translateZ(-120); //沿Z轴正方向平移120
      scene.add(mesh1); //网格模型添加到场景中

      var geometry3 = new THREE.CylinderGeometry(50, 50, 100, 5);
      var material3 = new THREE.MeshLambertMaterial({
        color: 0xffff00,
        transparent: true,
        opacity: 0.3,
        wireframe: true,
      });
      var mesh3 = new THREE.Mesh(geometry3, material3); //网格模型对象Mesh
      // mesh3.translateX(120); //球体网格模型沿Y轴正方向平移120
      mesh3.position.set(120, 0, 0); //设置mesh3模型对象的xyz坐标为120,0,0
      scene.add(mesh3);

      /**
       * 创建 BufferGeometry 实现自定义几何体（通过顶点数据）
       */
      var geometry4 = new THREE.BufferGeometry(); //创建一个Buffer类型几何体对象
      //类型数组创建顶点数据
      var vertices4 = new Float32Array([
        0,
        0,
        0, //顶点1坐标
        50,
        0,
        0, //顶点2坐标
        0,
        100,
        0, //顶点3坐标
        0,
        0,
        10, //顶点4坐标
        0,
        0,
        100, //顶点5坐标
        50,
        0,
        10, //顶点6坐标
      ]);
      // 创建属性缓冲区对象
      var attribue4 = new THREE.BufferAttribute(vertices4, 3); //3个为一组，表示一个顶点的xyz坐标
      // 设置几何体attributes属性的位置属性
      geometry4.attributes.position = attribue4;
      // 三角面(网格)渲染模式
      var material4 = new THREE.MeshBasicMaterial({
        color: 0x0000ff, //三角面颜色
        side: THREE.DoubleSide, //两面可见
      }); //材质对象
      var mesh4 = new THREE.Mesh(geometry4, material4); //网格模型对象Mesh
      mesh4.position.set(-120, 0, 0);
      scene.add(mesh4);

      /**
       * 光源设置
       */
      //点光源
      var point = new THREE.PointLight(0xffffff);
      point.position.set(100, 200, 300); //点光源位置
      scene.add(point); //点光源添加到场景中
      //环境光
      var ambient = new THREE.AmbientLight(0x000);
      scene.add(ambient);
      // console.log(scene)
      // console.log(scene.children)
      /**
       * 相机设置
       */
      var width = window.innerWidth; //窗口宽度
      var height = window.innerHeight; //窗口高度
      var k = width / height; //窗口宽高比
      var s = 300; //三维场景显示范围控制系数，系数越大，显示的范围越大
      //创建相机对象
      var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
      camera.position.set(60, 60, 60); //设置相机位置
      camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
      /**
       * 创建渲染器对象
       */
      var renderer = new THREE.WebGLRenderer();
      renderer.setSize(width, height); //设置渲染区域尺寸
      renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
      document.body.appendChild(renderer.domElement); //body元素中插入canvas对象

      //执行渲染操作   指定场景、相机作为参数--渲染一帧
      // renderer.render(scene, camera);

      // 旋转，每1/60秒左右，旋转固定弧度
      // function render() {
      //   renderer.render(scene, camera);
      //   mesh.rotateY(0.01);
      //   requestAnimationFrame(render);
      // }
      // render();

      // 旋转，每1/60秒左右，旋转时间线性的弧度（更接近匀速）
      // const render = RAFTime((t) => {
      //   renderer.render(scene, camera);
      //   mesh.rotateY(0.001 * t);
      // });
      // render();

      // 监听鼠标、键盘事件，实现 旋转/缩放/平移
      function render() {
        renderer.render(scene, camera); //执行渲染操作
      }
      // 启动渲染
      render();
      // 创建，轨迹控件
      var controls = new THREE.OrbitControls(camera, renderer.domElement);
      // 监听鼠标、键盘事件
      controls.addEventListener("change", render);

      // 算法
      const sourceData = [
        {
          id: 1,
          name: "南昌大学",
          children: [
            {
              id: 11,
              name: "儿科学(100202)",
            },
            {
              id: 12,
              name: "青山湖北校区",
              children: [
                {
                  id: 121,
                  name: "分析测试中心",
                  children: [
                    {
                      id: 1211,
                      name: "分测子级",
                      children: [
                        {
                          id: 12111,
                          name: "最内层喽",
                        },
                      ],
                    },
                  ],
                },
                {
                  id: 122,
                  name: "食品科学与资源挖掘全国重点实验室",
                },
              ],
            },
          ],
        },
        {
          id: 2,
          name: "西京学院",
        },
      ];

      // 如何筛选 以上数据
      // 遍历所有的数据，如果是 最内层的数据 且 匹配不到，则删除
      let queryStr = "分析测试中心";
      let totalDeep = 1;

      // 递归函数
      const findDeep = (arr, parentNode, currentDeep) => {
        // 层数计算，得到最深的层数
        if (currentDeep && currentDeep >= totalDeep) {
          totalDeep = currentDeep++;
        } else {
          currentDeep = 1;
        }

        for (let i = arr.length - 1; i >= 0; i--) {
          // 包含子节点
          if (!!arr[i].children && arr[i].children.length > 0) {
            findDeep(arr[i].children, arr[i], currentDeep);
          } else {
            console.log("arr[i].name---", arr[i].name);
            if (!arr[i].name.includes(queryStr)) {
              arr.splice(i, 1);
              // 如果当前数组为空，则删除改数组
              if (!!parentNode && arr.length === 0) {
                delete parentNode.children;
              }
            }
          }
        }
      };
      // 先执行一次，计算出最大层深
      findDeep(sourceData);
      for (let i = 0; i < totalDeep; i++) {
        findDeep(sourceData);
      }
      console.log("sourceData---", sourceData);
      console.log("totalDeep---", totalDeep);
    </script>
  </body>
</html>
